package com.icongyou.enterprise.talent_analysis.scheduler;

import com.icongyou.enterprise.data_aggregation.entity.GradeEntity;
import com.icongyou.enterprise.data_aggregation.entity.SubmissionEntity;
import com.icongyou.enterprise.data_aggregation.mapper.DataAggregationMapper;
import com.icongyou.enterprise.talent_analysis.entity.DataSyncLog;
import com.icongyou.enterprise.talent_analysis.event.StudentDataChangeEvent;
import com.icongyou.enterprise.talent_analysis.mapper.DataSyncLogMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 学生数据同步调度器
 * 定时检查学生端数据变更，触发画像更新
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class StudentDataSyncScheduler {

    private final DataAggregationMapper dataAggregationMapper;
    private final DataSyncLogMapper dataSyncLogMapper;
    private final ApplicationEventPublisher eventPublisher;

    /**
     * 每12小时同步一次学生数据变更
     * 适合批量处理，减少数据库负载
     */
    @Scheduled(fixedDelay = 43200000, initialDelay = 60000)
    public void syncStudentDataChanges() {
        
        try {
            // 检查各个数据表的变更
            syncSubmissions();
            syncGrades();
            
        } catch (Exception e) {
        }
    }

    /**
     * 同步作业提交数据（优化版：使用增量查询）
     */
    private void syncSubmissions() {
        LocalDateTime lastSyncTime = dataSyncLogMapper.getLastSyncTime("submissions");
        if (lastSyncTime == null) {
            // 首次同步，设置为24小时前
            lastSyncTime = LocalDateTime.now().minusDays(1);
        }
        
        
        // 使用增量查询直接获取新提交记录
        List<SubmissionEntity> newSubmissions = dataAggregationMapper.selectAllNewSubmissionsSince(lastSyncTime);
        
        if (newSubmissions.isEmpty()) {
            return;
        }
        
        
        // 收集涉及的学生ID（去重）
        Set<String> changedStudents = new HashSet<>();
        for (SubmissionEntity submission : newSubmissions) {
            changedStudents.add(submission.getStudentId());
            
            // 如果是团队任务，需要通知所有团队成员
            if (submission.getTeamId() != null && submission.getContributionRate() != null) {
                for (SubmissionEntity.ContributionItem item : submission.getContributionRate()) {
                    changedStudents.add(item.getStudentId());
                }
            }
        }
        
        // 为变更的学生触发画像更新
        for (String studentId : changedStudents) {
            eventPublisher.publishEvent(
                new StudentDataChangeEvent(this, studentId, "SUBMISSION_SYNC")
            );
            
            // 记录同步日志
            DataSyncLog syncLog = new DataSyncLog();
            syncLog.setId(UUID.randomUUID().toString());
            syncLog.setTableName("submissions");
            syncLog.setRecordId(studentId + "_" + System.currentTimeMillis());
            syncLog.setStudentId(studentId);
            syncLog.setChangeType("SYNC");
            syncLog.setRecordTime(LocalDateTime.now());
            syncLog.setSyncTime(LocalDateTime.now());
            dataSyncLogMapper.insert(syncLog);
        }
    }

    /**
     * 同步成绩数据（优化版：使用增量查询）
     */
    private void syncGrades() {
        LocalDateTime lastSyncTime = dataSyncLogMapper.getLastSyncTime("grades");
        if (lastSyncTime == null) {
            lastSyncTime = LocalDateTime.now().minusDays(1);
        }
        
        
        // 使用增量查询直接获取新成绩记录
        List<GradeEntity> newGrades = dataAggregationMapper.selectAllNewGradesSince(lastSyncTime);
        
        if (newGrades.isEmpty()) {
            return;
        }
        
        
        // 收集涉及的学生ID（通过submission_id查询）
        Set<String> changedStudents = new HashSet<>();
        for (GradeEntity grade : newGrades) {
            // 通过submission_id查询对应的提交记录
            String submissionId = grade.getSubmissionId();
            if (submissionId != null) {
                // 需要查询submission表获取studentId
                // 这里简化处理，直接从缓存或数据库查询
                try {
                    // 使用已有的getStudentGrade方法反向查找（不高效但可用）
                    // 正常情况下应该添加一个直接查询submission的方法
                    List<String> allStudents = dataAggregationMapper.getAllStudentIds();
                    for (String sid : allStudents) {
                        var courses = dataAggregationMapper.getStudentCourse(sid);
                        for (var course : courses) {
                            var assignments = dataAggregationMapper.getStudentAssignmentScore(sid, course.getCourseId());
                            for (var assignment : assignments) {
                                var submissions = dataAggregationMapper.getStudentSubmission(sid, assignment.getAssignmentId());
                                for (var submission : submissions) {
                                    if (submission.getSubmissionId().equals(submissionId)) {
                                        changedStudents.add(sid);
                                        // 如果是团队任务，通知所有团队成员
                                        if (submission.getTeamId() != null && submission.getContributionRate() != null) {
                                            for (SubmissionEntity.ContributionItem item : submission.getContributionRate()) {
                                                changedStudents.add(item.getStudentId());
                                            }
                                        }
                                        break;
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                }
            }
        }
        
        // 为变更的学生触发画像更新
        for (String studentId : changedStudents) {
            eventPublisher.publishEvent(
                new StudentDataChangeEvent(this, studentId, "GRADE_SYNC")
            );
            
            DataSyncLog syncLog = new DataSyncLog();
            syncLog.setId(UUID.randomUUID().toString());
            syncLog.setTableName("grades");
            syncLog.setRecordId(studentId + "_" + System.currentTimeMillis());
            syncLog.setStudentId(studentId);
            syncLog.setChangeType("SYNC");
            syncLog.setRecordTime(LocalDateTime.now());
            syncLog.setSyncTime(LocalDateTime.now());
            dataSyncLogMapper.insert(syncLog);
        }
    }
}
